package com.awesome.todo.activities;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.DatePicker;
import android.widget.ImageView;
import android.widget.ListView;

import com.awesome.todo.ListViewAdapter;
import com.awesome.todo.R;
import com.awesome.todo.Task;
import com.awesome.todo.Task.Category;
import com.awesome.todo.database.TaskDataSource;

/**
 * This class displays the todo list to the user.
 * 
 * @author Doug Black
 * 
 */

public class TaskListActivity extends Activity {

	ListViewAdapter listViewAdapter;

	static ListView taskListView;
	TaskDataSource taskDataSource;
	ArrayList<Task> taskList;
	ImageView newTaskButton;
	ImageView filterButton;
	ImageView mapButton;
	static long currentUserId;
	Category selectedCategory;
	final String[] filterStrings = { "Show all", "Filter by date", "Filter by category", "Filter by completed" };
	int targetYear;
	int targetMonth;
	int targetDay;
	static final int DATE_DIALOG_ID = 0;
	static final int CATEGORY_DIALOG_ID = 1;
	static final int FILTER_DIALOG_ID = 2;
	Context cxt;

	/**
	 * Called on create. Sets up the UI.
	 */
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.tasklist);
		
		if (getIntent().getExtras() != null)
			currentUserId = getIntent().getExtras().getLong("userId");

		final Calendar cal = Calendar.getInstance();
		targetYear = cal.get(Calendar.YEAR);
		targetMonth = cal.get(Calendar.MONTH);
		targetDay = cal.get(Calendar.DAY_OF_MONTH);
		cxt = this;
		taskDataSource = new TaskDataSource(this.getApplicationContext());
		taskList = taskDataSource.getAllTasksForUserId(currentUserId);

		newTaskButton = (ImageView) findViewById(R.id.newTaskButton);
		taskListView = (ListView) findViewById(R.id.taskListView);
		mapButton = (ImageView) findViewById(R.id.mapButton);
		filterButton = (ImageView) findViewById(R.id.filterButton);
		listViewAdapter = new ListViewAdapter(this, taskList);
		taskListView.setAdapter(listViewAdapter);
		newTaskButton.setOnTouchListener(new OnTouchListener() {

			public boolean onTouch(View v, MotionEvent event) {
				if (event.getAction() == MotionEvent.ACTION_DOWN) {
					v.setBackgroundColor(cxt.getResources().getColor(R.color.LightSlateGray));
					return true;
				} else if (event.getAction() == MotionEvent.ACTION_UP) {
					v.setBackgroundColor(cxt.getResources().getColor(R.color.DimGray));
					Intent intent = new Intent(v.getContext(), NewTaskActivity.class);
					intent.putExtra("userId", currentUserId);
					startActivity(intent);
					return true;
				}
				return false;
			}

		});

		filterButton.setOnTouchListener(new OnTouchListener() {

			public boolean onTouch(View view, MotionEvent event) {

				if (event.getAction() == MotionEvent.ACTION_DOWN) {
					view.setBackgroundColor(cxt.getResources().getColor(R.color.LightSlateGray));
					return true;
				} else if (event.getAction() == MotionEvent.ACTION_UP) {
					view.setBackgroundColor(cxt.getResources().getColor(R.color.DimGray));
					showDialog(FILTER_DIALOG_ID);
					return true;
				}
				return false;
			}

		});
		
		mapButton.setOnTouchListener(new OnTouchListener() {

			public boolean onTouch(View view, MotionEvent event) {

				if (event.getAction() == MotionEvent.ACTION_DOWN) {
					view.setBackgroundColor(cxt.getResources().getColor(R.color.LightSlateGray));
					return true;
				} else if (event.getAction() == MotionEvent.ACTION_UP) {
					view.setBackgroundColor(cxt.getResources().getColor(R.color.DimGray));
					Intent intent = new Intent(view.getContext(), TaskMapActivity.class);
					startActivity(intent);
					return true;
				}
				return false;
			}

		});

	}
	
	public ListView getTaskListView() {
		return taskListView;
	}
	
	public void setFilterCategory(Category category) {
		selectedCategory = category;
	}

	/**
	 * This shows all items for this user.
	 */
	public void showAll() {
		taskList = taskDataSource.getAllTasksForUserId(currentUserId);
		((ListViewAdapter) taskListView.getAdapter()).setTasks(taskList);
		((ListViewAdapter) taskListView.getAdapter()).notifyDataSetChanged();
	}

	/**
	 * Extracts the names of the tasks from all of the Tasks owned by the user
	 * and puts them into a String array to be consumed by the ListView adapter.
	 * 
	 * @param taskList
	 *            the list of all tasks owned by the user
	 * @return a String array containing only the names of the tasks owned by
	 *         the user.
	 */
	public String[] getTaskNames(ArrayList<Task> taskList) {

		String[] taskNames = { "No tasks" };
		if (!(taskList.size() == 0)) {
			taskNames = new String[taskList.size()];
			for (int i = 0; i < taskList.size(); i++) {
				taskNames[i] = taskList.get(i).getName();
			}
		}

		return taskNames;

	}

	/**
	 * Called when this activity is brought back to the front. This is
	 * overridden to refresh the ListView so the task list gets updated after
	 * the User creates a new Task.
	 */
	@Override
	public void onResume() {
		super.onResume();

		taskList = taskDataSource.getAllTasksForUserId(currentUserId);

		ListView listView = (ListView) findViewById(R.id.taskListView);
		listViewAdapter = new ListViewAdapter(this, taskList);
		listView.setAdapter(listViewAdapter);

	}

	/**
	 * Filters based on the selected category
	 * 
	 * @return
	 */

	public ArrayList<Task> filterCats() {

		ArrayList<Task> tasks = taskDataSource.getAllTasksForUserId(currentUserId);
		ArrayList<Task> filteredTasks = new ArrayList<Task>();
		Iterator<Task> it = tasks.iterator();

		while (it.hasNext()) {

			Task nextIt = (Task) it.next();
			if (nextIt.getType() == selectedCategory) {
				filteredTasks.add(nextIt);
			}
		}
		return filteredTasks;
	}

	/**
	 * Filters only the items that haven't been completed
	 * 
	 * @return
	 */
	public ArrayList<Task> filterCompletion() {

		ArrayList<Task> tasks = taskDataSource.getAllTasksForUserId(currentUserId);
		ArrayList<Task> filteredTasks = new ArrayList<Task>();
		Iterator<Task> it = tasks.iterator();

		while (it.hasNext()) {

			Task nextIt = (Task) it.next();
			if (nextIt.getCompleted() == false) {
				filteredTasks.add(nextIt);
			}
		}
		return filteredTasks;
	}

	/**
	 * Filters only items after the selected date.
	 * 
	 * @param targetDate
	 * @return
	 */
	public ArrayList<Task> filterDate(String targetDate) {
		ArrayList<Task> tasks = taskDataSource.getAllTasksForUserId(currentUserId);
		ArrayList<Task> filteredTasks = new ArrayList<Task>();
		Iterator<Task> it = tasks.iterator();

		while (it.hasNext()) {

			Task nextIt = (Task) it.next();
			try {
				if (compareDate(targetDate, nextIt.getDate())) {
					filteredTasks.add(nextIt);
				}
			} catch (ParseException pe) {
				Log.e("ERROR", "Parse exception.");
			}
		}

		Log.i("INFO", "Filtered tasks: " + filteredTasks.toString());
		return filteredTasks;
	}

	/**
	 * Compares two date strings of the format "mm/dd/yyyy"
	 * 
	 * @param targetDateString
	 * @param taskDateString
	 * @return
	 * @throws ParseException
	 */
	public boolean compareDate(String targetDateString, String taskDateString) throws ParseException {

		SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
		Date targetDate = dateFormat.parse(targetDateString);
		Date taskDate = dateFormat.parse(taskDateString);

		Log.i("INFO", "Target date: " + targetDate.toLocaleString());
		Log.i("INFO", "Task date: " + taskDate.toLocaleString());

		if (targetDate.getTime() <= taskDate.getTime()) {
			return true;
		}
		return false;

	}

	/**
	 * Shows the date dialog.
	 */
	public void filterByDate() {
		showDialog(DATE_DIALOG_ID);
	}

	/**
	 * Shows the category dialog
	 */
	public void filterByCategory() {
		showDialog(CATEGORY_DIALOG_ID);

	}

	/**
	 * Shows only not completed items.
	 */
	public void filterByCompleted() {
		taskList = filterCompletion();
		((ListViewAdapter) taskListView.getAdapter()).setTasks(taskList);
		((ListViewAdapter) taskListView.getAdapter()).notifyDataSetChanged();
	}

	private DatePickerDialog.OnDateSetListener dateSetListener = new DatePickerDialog.OnDateSetListener() {

		public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) {
			targetYear = year;
			targetMonth = monthOfYear + 1;
			targetDay = dayOfMonth;
			String targetMonthString, targetDayString, targetYearString = "";
			if (targetMonth < 10) {
				targetMonthString = "0" + targetMonth;
			} else {
				targetMonthString = "" + targetMonth;
			}
			if (targetDay < 10) {
				targetDayString = "0" + targetDay;
			} else {
				targetDayString = "" + targetDay;
			}
			targetYearString = "" + targetYear;
			String targetDateString = "" + targetMonthString + "/" + targetDayString + "/" + targetYearString;
			taskList = filterDate(targetDateString);
			((ListViewAdapter) taskListView.getAdapter()).setTasks(taskList);
			((ListViewAdapter) taskListView.getAdapter()).notifyDataSetChanged();
		}
	};

	/**
	 * Creates the corresponding dialog.
	 */
	protected Dialog onCreateDialog(int id) {

		AlertDialog dialog = null;
		AlertDialog.Builder builder = null;

		switch (id) {
		case DATE_DIALOG_ID:
			return new DatePickerDialog(this, dateSetListener, targetYear, targetMonth, targetDay);
		case CATEGORY_DIALOG_ID:
			final CharSequence[] categories = { "Personal", "School", "Work" };
			builder = new AlertDialog.Builder(this);
			builder.setTitle("Choose category");
			builder.setItems(categories, new DialogInterface.OnClickListener() {

				public void onClick(DialogInterface di, int pos) {
					selectedCategory = Category.valueOf(categories[pos].toString());
					taskList = filterCats();
					((ListViewAdapter) taskListView.getAdapter()).setTasks(taskList);
					((ListViewAdapter) taskListView.getAdapter()).notifyDataSetChanged();
				}
			});
			dialog = builder.create();
			return dialog;

		case FILTER_DIALOG_ID:
			final CharSequence[] filterOptions = { "Show all", "Filter by date", "Filter by category",
					"Filter by completed" };
			builder = new AlertDialog.Builder(cxt);
			builder.setTitle("Choose filter");
			builder.setItems(filterOptions, new DialogInterface.OnClickListener() {

				public void onClick(DialogInterface di, int pos) {
					switch (pos) {

					case 0:
						showAll();
						break;
					case 1:
						filterByDate();
						break;
					case 2:
						filterByCategory();
						break;
					case 3:
						filterByCompleted();
						break;
					}
				}
			});
			dialog = builder.create();
			return dialog;

		}
		return null;
	}

}